require "wondercap/lib/utils/dependency_resolver"
require "yaml"

name_filter :add_build_dependent do |names, configurations, options|
  local_area = Wondercap::Deployment::Area.find_by_name("local")
  next names unless local_area && local_area.current_snapshot

  confs = {}
  getter = lambda do |name|
    next confs[name] if confs.key? name
      
    dep = local_area.current_snapshot.find_deployment_by_name(name.to_s)
    return [] unless outer_configuration.configuration_defined?(name) && dep

    conf = outer_configuration.configuration_clone(name)
    conf.use(:revision => :explicit) { set :revision, dep.revision }
    conf.use :dependencies => :stored_build_dependencies

    confs[name] = conf.build_dependencies
  end

  deps_resolver = DependencyResolver.new(getter)
  deps_resolver.add_dependent(names, local_area.current_snapshot.deployments.map { |dep| dep.name })
end

name_filter :add_build_required do |names, configurations, options|
  return names if options[:remote]
  
  getter = lambda do |name|
    return [] unless configurations[name]
    
    conf = configurations[name]
    conf.use :revision => :current_local_snapshot_with_fallback unless names.include? name    
    conf.build_dependencies
  end
  
  deps_resolver = Wondercap::DependencyResolver.new(getter)
  deps_resolver.add_required(names).to_a
end

name_filter :order_by_build_dependencies do |names, configurations, options|
  return names if options[:remote]

  getter = lambda do |name|
    return [] unless configurations[name]

    #TODO: check if it works without adding conf.runtime_dependencies
    conf = configurations[name]
    conf.build_dependencies + conf.runtime_dependencies
  end

  deps_resolver = Wondercap::DependencyResolver.new(getter)
  deps_resolver.order_by_dependencies(names).to_a
end

extension :dependencies => :build_dependencies do
  set :build_dependencies, [], :on_fetch => :fill_build_dependencies
  task :fill_build_dependencies do
  end
  
  task :patch_dist do
    execute_previous
    
    build_deps_file = File.join(revision_build.patched_dist_path, ".build_deps")
    open(build_deps_file, "w") do |fio|
      fio.write(build_dependencies.to_yaml)
    end
  end
  
end

extension :build_dependencies => :explicit do
  task :fill_build_dependencies do
  end
end

extension :dependencies => :stored_build_dependencies do
  task :fill_build_dependencies do
    build_deps_file = File.join(revision_build.patched_dist_path, ".build_deps")
    if File.exists? build_deps_file
      stored_deps = open(build_deps_file, "r") do |fio|
        YAML::load(fio.read)
      end
      build_dependencies.concat stored_deps
    end
  end
end

configuration :base do
  use :dependencies => :build_dependencies
end

after "wondercap:extract_filters" do
  if top_task.fully_qualified_name == "wondercap:deploy"
    unless fetch(:remote, false)
      filters << :add_build_required unless fetch(:without_build_deps, false)
      filters << :order_by_build_dependencies
    end
  end
end
